#include "GLUniformBlocks.h"
#include "GLState.h"
#include <GL/glew.h>
using namespace Umikaze::Core;

std::unique_ptr<GlUniformBocks> GlUniformBocks::_instance = nullptr;

uint32_t GlUniformBocks::genBuffer() {
  auto &state = GlState::instance();
  uint32_t location = 0;
  uint32_t ubo;
  glGenBuffers(1, &ubo);
  state->bindUniformBuffer(ubo);
  location = getEmptyLocation();
  glBindBufferBase(GL_UNIFORM_BUFFER, location, ubo);
  _uniformBlocks.insert({ubo, {location, 0, 0}});
  return ubo;
}

void GlUniformBocks::updateBuffer(uint32_t ubo, void *data, size_t size) {
  if (auto iter = _uniformBlocks.find(ubo); iter != _uniformBlocks.end()) {
    auto &state = GlState::instance();
    auto &cache = iter->second;
    if (cache.needUpdate(data, size)) {
      cache._data = data;
      cache._size = size;
      state->bindUniformBuffer(ubo);
      glBufferData(GL_UNIFORM_BUFFER, size, data, GL_STATIC_DRAW);
    }
  } else {
    std::cerr << "错误的ubo，或该ubo已经被删除" << std::endl;
  }
}

uint32_t GlUniformBocks::getLocation(uint32_t ubo) {
  if (auto iter = _uniformBlocks.find(ubo); iter != _uniformBlocks.end()) {
    return iter->second._location;
  } else {
    std::cerr << "没有这个ubo" << std::endl;
    return 99999999;
  }
}